import Tablero
import Othello
import HUnit
import Maybe

-- evaluar t para correr todos los tests
t = runTestTT allTests

allTests = test [ 
	"triviales" ~: testsTriviales,
	"tablero" ~: testsTablero,
	"poner" ~: testsPoner,
	"desplazar" ~: testsDesplazar,
	"generar" ~: testsGenerar,
	"posicionesAInvertir" ~: testsPosicionesAInvertir,
	"invertirTodas" ~: testsInvertirTodas,
	"testsJugadasPosibles" ~: testsJugadasPosibles,
	"mejorJugada" ~: testsMejorJugada,
	"ganador" ~: testsGanador
	]

testsTriviales = test [
	1 ~=? 1,
	2 ~=? 2,
	[1,2] ~=? [1,2],
	[1,2] ~~? [2,1]
	]

-- Test Ejercicio1	
testsTablero = test [
	Nothing ~=? contenido d_4 vacio,
	Nothing ~=? contenido e_5 vacio,
	Nothing ~=? contenido e_4 vacio,
	Nothing ~=? contenido d_5 vacio,
	_N ~=? fromJust (contenido d_4 tableroInicial),
	_N ~=? fromJust (contenido e_5 tableroInicial),
	_B ~=? fromJust (contenido e_4 tableroInicial),
	_B ~=? fromJust (contenido d_5 tableroInicial),
	Nothing ~=? contenido a_1 tableroInicial
	]
	
-- Test Ejercicio 2
testsPoner = test [
	Nothing ~=? contenido a_1 vacio,
	Nothing ~=? contenido b_2 vacio,
	Nothing ~=? contenido c_3 vacio,
	Nothing ~=? contenido d_4 vacio,
	_N ~=? fromJust (contenido a_1 (poner a_1 Negro vacio)),
	_N ~=? fromJust (contenido b_2 (poner b_2 Negro vacio)),
	_B ~=? fromJust (contenido c_3 (poner c_3 Blanco vacio)),
	_B ~=? fromJust (contenido d_4 (poner d_4 Blanco vacio))
	]
	
-- Test Ejercicio 3
testsDesplazar = test [
	desplazarColumna 1 c_1 ~=? d_1,
	desplazarFila (-2) c_4 ~=? c_2
	]
	
-- Test Ejercicio 4
testsGenerar = test [
	generar f_5 (desplazarFila 1) ~=? [f_5, f_6, f_7, f_8],
	generar f_5 ((desplazarColumna 1).(desplazarFila 1)) ~=? [f_5, g_6, h_7]
	]

-- Test Ejercicio 5	
testsPosicionesAInvertir = test [
    (posicionesAInvertir c_4 (poner c_4 Blanco tableroInicial)) ~=? [d_4],
    (posicionesAInvertir c_4 (poner c_3 Negro (poner c_4 Blanco tableroInicial))) ~=? [d_4]
	]

-- Test Ejercicio 6	
-- Se fija si se invirtieron los colores en las posiciones del tableroInicial
testsInvertirTodas = test [
    _B ~=? fromJust ((contenido d_4 (invertirTodas [d_4, e_5, e_4, d_5] tableroInicial))),
	_B ~=? fromJust ((contenido e_5 (invertirTodas [d_4, e_5, e_4, d_5] tableroInicial))),
	_N ~=? fromJust ((contenido e_4 (invertirTodas [d_4, e_5, e_4, d_5] tableroInicial))),
	_N ~=? fromJust ((contenido d_5 (invertirTodas [d_4, e_5, e_4, d_5] tableroInicial))) 
	]	

-- Test Ejercicio 8
testsJugadasPosibles = test [
    [M ('e',8),M ('f',8),M ('g',7)]~=? [fst x | x <- (jugadasPosibles juego1)]	
	]
	
-- Test Ejercicio 11	
testsMejorJugada = test [
	M e_8 ~=? mejorJugada valuacionOthello (podar 3 (arbolDeJugadas juego1))
	]	

-- Test Ejercicio 12
testsGanador = test [
    Nothing ~=? ganador (J Blanco tableroInicial), 	
	_N ~=? fromJust (ganador (J Blanco todosNegros)),
	_B ~=? fromJust (ganador (fromJust juegoCompleto))
	]	
	
-- idem ~=? pero sin importar el orden
(~~?) :: (Ord a, Eq a, Show a) => [a] -> [a] -> Test
expected ~~? actual = (sort expected) ~=? (sort actual)
	where
		sort = foldl (\r e -> push r e) []
		push r e = (filter (e<=) r) ++ [e] ++ (filter (e>) r)

(~~) :: (Ord a, Eq a, Show a) => [a] -> [a] -> Bool
expected ~~ actual = (sort expected) == (sort actual)
	where
		sort = foldl (\r e -> push r e) []
		push r e = (filter (e<=) r) ++ [e] ++ (filter (e>) r)

-- Tableros
todosNegros = T (\_ -> Just Negro)

ponerTodos c t = foldr ((flip poner) c) t

tablero1 = ponerTodos _B tableroInicial [d_3, f_2, f_3, g_1, g_3, f_1, e_1, h_1, d_6, c_4, h_3, h_4, b_6, b_4, c_1, b_3, g_6, d_8, c_7, h_5, b_8, b_1, a_8, a_6, a_3, a_1, e_7, h_6, g_8, h_8] 
tablero2 = ponerTodos _N tablero1 [e_3, e_2, g_2, g_4, h_2, d_2, d_1, c_5, d_7, f_4, c_3, f_5, b_5, c_2, a_4, c_6, g_5, e_6, h_7, c_8, b_2, b_7, a_7, a_5, a_2, f_6, f_7]

-- Juegos
juego1 = J Blanco tablero2

juegoCompleto = jugar (M f_8) (fromJust (jugar (M g_7) (fromJust (jugar (M e_8) juego1))))

-- constantes para que los tests sean más legibles		
_N = Negro
_B = Blanco
a_1 = ('a',1::Int)
b_1 = ('b',1::Int)
c_1 = ('c',1::Int)
d_1 = ('d',1::Int)
e_1 = ('e',1::Int)
f_1 = ('f',1::Int)
g_1 = ('g',1::Int)
h_1 = ('h',1::Int)

a_2 = ('a',2::Int)
b_2 = ('b',2::Int)
c_2 = ('c',2::Int)
d_2 = ('d',2::Int)
e_2 = ('e',2::Int)
f_2 = ('f',2::Int)
g_2 = ('g',2::Int)
h_2 = ('h',2::Int)

a_3 = ('a',3::Int)
b_3 = ('b',3::Int)
c_3 = ('c',3::Int)
d_3 = ('d',3::Int)
e_3 = ('e',3::Int)
f_3 = ('f',3::Int)
g_3 = ('g',3::Int)
h_3 = ('h',3::Int)

a_4 = ('a',4::Int)
b_4 = ('b',4::Int)
c_4 = ('c',4::Int)
d_4 = ('d',4::Int)
e_4 = ('e',4::Int)
f_4 = ('f',4::Int)
g_4 = ('g',4::Int)
h_4 = ('h',4::Int)

a_5 = ('a',5::Int)
b_5 = ('b',5::Int)
c_5 = ('c',5::Int)
d_5 = ('d',5::Int)
e_5 = ('e',5::Int)
f_5 = ('f',5::Int)
g_5 = ('g',5::Int)
h_5 = ('h',5::Int)

a_6 = ('a',6::Int)
b_6 = ('b',6::Int)
c_6 = ('c',6::Int)
d_6 = ('d',6::Int)
e_6 = ('e',6::Int)
f_6 = ('f',6::Int)
g_6 = ('g',6::Int)
h_6 = ('h',6::Int)

a_7 = ('a',7::Int)
b_7 = ('b',7::Int)
c_7 = ('c',7::Int)
d_7 = ('d',7::Int)
e_7 = ('e',7::Int)
f_7 = ('f',7::Int)
g_7 = ('g',7::Int)
h_7 = ('h',7::Int)

a_8 = ('a',8::Int)
b_8 = ('b',8::Int)
c_8 = ('c',8::Int)
d_8 = ('d',8::Int)
e_8 = ('e',8::Int)
f_8 = ('f',8::Int)
g_8 = ('g',8::Int)
h_8 = ('h',8::Int)
